// 尝试导入notify.mp3，如果不存在使用默认声音
let notifySound: string;
try {
  // 动态导入可能会失败，使用try/catch处理
  notifySound = import.meta.env.BASE_URL + "src/assets/sounds/notify.mp3";
} catch (e) {
  // 如果导入失败，使用短WAV数据作为备选
  console.warn("无法加载notify.mp3，将使用默认声音");
  notifySound =
    "data:audio/wav;base64,UklGRigAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQAAAAMAAAAAAAAACoAAAA=";
}

/**
 * 音频管理工具类
 */

class SoundManager {
  private static instance: SoundManager;
  private audioContext: AudioContext | null = null;
  private enabled: boolean = true;
  private notificationPermissionGranted: boolean = false;
  private audioElement: HTMLAudioElement | null = null;

  private constructor() {
    // 尝试初始化Web Audio API
    try {
      window.AudioContext =
        window.AudioContext || (window as any).webkitAudioContext;
      if (window.AudioContext) {
        this.audioContext = new AudioContext();
        console.log("音频上下文已初始化");
      } else {
        console.warn("当前浏览器不支持Web Audio API");
      }
    } catch (e) {
      console.error("初始化音频上下文失败:", e);
    }

    // 初始化音频元素
    this.initAudioElement();

    // 检查通知权限
    this.checkNotificationPermission();
  }

  /**
   * 初始化音频元素
   */
  private initAudioElement(): void {
    try {
      this.audioElement = new Audio();
      // 设置音频源
      this.audioElement.src = notifySound;
      this.audioElement.preload = "auto";
      this.audioElement.volume = 0.5;

      // 记录音频加载状态
      this.audioElement.addEventListener("canplaythrough", () => {
        console.log("音频文件已加载完成");
      });

      this.audioElement.addEventListener("error", e => {
        console.error("音频文件加载失败:", e);
        // 如果mp3加载失败，尝试使用备用声音
        if (
          this.audioElement &&
          this.audioElement.src !==
            "data:audio/wav;base64,UklGRigAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQAAAAMAAAAAAAAACoAAAA="
        ) {
          console.log("尝试使用备用声音");
          this.audioElement.src =
            "data:audio/wav;base64,UklGRigAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQAAAAMAAAAAAAAACoAAAA=";
        }
      });

      // 为了解决浏览器自动播放限制，预加载并尝试静音播放一次
      this.audioElement.muted = true;
      const playPromise = this.audioElement.play();
      if (playPromise !== undefined) {
        playPromise
          .then(() => {
            // 播放成功，重置并暂停
            this.audioElement!.pause();
            this.audioElement!.currentTime = 0;
            this.audioElement!.muted = false;
            console.log("音频元素初始化成功");
          })
          .catch(error => {
            console.warn("音频元素初始化时静音播放失败:", error);
          });
      }
    } catch (error) {
      console.error("初始化音频元素失败:", error);
    }
  }

  /**
   * 检查通知权限
   */
  private async checkNotificationPermission(): Promise<void> {
    // 确认浏览器支持通知
    if (!("Notification" in window)) {
      console.warn("此浏览器不支持通知");
      return;
    }

    // 检查是否已有权限
    if (Notification.permission === "granted") {
      this.notificationPermissionGranted = true;
      console.log("通知权限已授予");
    } else if (Notification.permission !== "denied") {
      // 请求通知权限
      try {
        const permission = await Notification.requestPermission();
        this.notificationPermissionGranted = permission === "granted";
        console.log("通知权限:", permission);
      } catch (error) {
        console.warn("请求通知权限失败:", error);
      }
    }
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): SoundManager {
    if (!SoundManager.instance) {
      SoundManager.instance = new SoundManager();
    }
    return SoundManager.instance;
  }

  /**
   * 播放消息提示音
   * @param isMine 是否是自己发送的消息
   * @param senderName 发送者姓名，用于通知
   * @param message 消息内容，用于通知
   */
  public playMessageSound(
    isMine: boolean = false,
    senderName?: string,
    message?: string
  ): void {
    // 如果是自己的消息或者音效被禁用，则不播放
    if (isMine || !this.enabled) return;

    // 尝试多种方式播放声音，提高兼容性
    this.playBeepSound();
    this.playNotificationSound();

    // 如果获得了通知权限，则显示通知
    if (this.notificationPermissionGranted && senderName) {
      this.showNotification(senderName, message || "发来新消息");
    }
  }

  /**
   * 使用Web Audio API生成声音
   */
  private playBeepSound(): void {
    try {
      // 确保音频上下文存在
      if (!this.audioContext) {
        console.warn("AudioContext不可用");
        return;
      }

      // 如果音频上下文被暂停，尝试恢复
      if (this.audioContext.state === "suspended") {
        this.audioContext.resume();
      }

      // 创建振荡器
      const oscillator = this.audioContext.createOscillator();
      const gainNode = this.audioContext.createGain();

      // 设置音调和类型
      oscillator.type = "sine"; // 正弦波，听起来比较清脆
      oscillator.frequency.setValueAtTime(880, this.audioContext.currentTime); // 880Hz，较高的音调

      // 连接节点
      oscillator.connect(gainNode);
      gainNode.connect(this.audioContext.destination);

      // 设置音量并快速衰减
      gainNode.gain.setValueAtTime(0.2, this.audioContext.currentTime);
      gainNode.gain.exponentialRampToValueAtTime(
        0.001,
        this.audioContext.currentTime + 0.2
      );

      // 播放声音
      oscillator.start();
      oscillator.stop(this.audioContext.currentTime + 0.2); // 0.2秒后停止

      console.log("播放Web Audio API提示音");
    } catch (error) {
      console.error("使用Web Audio API播放声音失败:", error);
    }
  }

  /**
   * 使用Audio API播放通知声音
   */
  private playNotificationSound(): void {
    try {
      // 如果已初始化的音频元素存在，使用它
      if (this.audioElement) {
        // 确保从头开始播放
        this.audioElement.currentTime = 0;

        // 播放音效
        const playPromise = this.audioElement.play();

        // 处理播放承诺
        if (playPromise !== undefined) {
          playPromise.catch(error => {
            console.warn("播放预加载的通知声音失败:", error);
            // 尝试创建新实例播放
            this.playWithNewAudioInstance();
          });
        }
      } else {
        // 如果预加载的音频元素不可用，尝试创建新实例
        this.playWithNewAudioInstance();
      }

      console.log("尝试播放通知声音");
    } catch (error) {
      console.error("使用Audio API播放声音失败:", error);
    }
  }

  /**
   * 使用新的音频实例播放
   */
  private playWithNewAudioInstance(): void {
    try {
      const tempAudio = new Audio(notifySound);
      tempAudio.volume = 0.5;

      // 处理加载错误
      tempAudio.addEventListener("error", () => {
        console.warn("无法加载音频文件，尝试使用备用声音");
        tempAudio.src =
          "data:audio/wav;base64,UklGRigAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQAAAAMAAAAAAAAACoAAAA=";
        tempAudio.play().catch(e => {
          console.error("播放备用声音失败:", e);
          this.triggerUserInteraction();
        });
      });

      const playPromise = tempAudio.play();
      if (playPromise !== undefined) {
        playPromise.catch(error => {
          console.warn("使用新音频实例播放失败:", error);
          // 如果播放失败，尝试触发用户交互
          this.triggerUserInteraction();
        });
      }
    } catch (error) {
      console.error("创建新音频实例失败:", error);
    }
  }

  /**
   * 显示系统通知
   */
  private showNotification(title: string, body: string): void {
    try {
      if (this.notificationPermissionGranted) {
        const notification = new Notification(title, {
          body: body,
          icon: "/favicon.ico", // 可以使用应用的图标
          silent: false // 让浏览器播放默认声音
        });

        // 3秒后自动关闭通知
        setTimeout(() => notification.close(), 3000);

        console.log("显示系统通知");
      }
    } catch (error) {
      console.error("显示系统通知失败:", error);
    }
  }

  /**
   * 触发用户交互，解决一些浏览器的自动播放限制
   */
  private triggerUserInteraction(): void {
    try {
      // 创建一个隐藏的按钮并模拟点击
      const tempButton = document.createElement("button");
      tempButton.style.display = "none";
      document.body.appendChild(tempButton);
      tempButton.click();
      document.body.removeChild(tempButton);
    } catch (error) {
      console.error("触发用户交互失败:", error);
    }
  }

  /**
   * 启用/禁用提示音
   */
  public toggleSound(enabled: boolean): void {
    this.enabled = enabled;
    console.log("提示音已" + (enabled ? "启用" : "禁用"));
  }

  /**
   * 获取当前提示音状态
   */
  public isSoundEnabled(): boolean {
    return this.enabled;
  }
}

export default SoundManager;
